home *** CD-ROM | disk | FTP | other *** search
/ Utilities Professional 1-1500 / Utilities Professional 1-1500 (1994)(WPD)[!].iso / 12511500 / var1450.dms / var1450.adf / TrackdiskDevice / TrackdiskDevice.doc < prev    next >
Text File  |  1992-04-27  |  26KB  |  746 lines

  1. 6    TRACKDISK DEVICE
  2.  
  3. 6.1  INTRODUCTION
  4.  
  5. All Amiga models are delivered with at least one internal
  6. disk drive, but you may connect up to three extra disk drives.
  7. The disk drivers are using normal double sided double density
  8. (2DD) 3 1/2" disks. 5 1/4" disks may also be used, but this is
  9. not supported by the trackdisk device. 
  10.  
  11. The trackdisk device consists of a set of low level routines
  12. which are used by other higher level processes like AmigaDOS.
  13. When you want to read and write data you should normally only
  14. use AmigaDOS or the special file commands in C. The trackdisk
  15. device should only be used when you want to write disk
  16. viewers/editors, or disk-copy programs.
  17.  
  18. Although the disk routines are normally considered to be very
  19. slow on the Amiga, it should be noted that it is actually not
  20. the disk drivers which are slow. AmigaDOS is using a very
  21. flexible disk operating system and because of this the disk
  22. drivers appears to be very slow. The low level routines are
  23. on the other hand very quick and are turbocharged with the
  24. "Blitter" (special coprocessor on the Amiga) which is
  25. specialized in moving large quantities of data extremely fast.
  26.  
  27. To read and write so called "raw data" with the lowlevel
  28. routines is much faster that to use the higher and more
  29. sophisticated AmigaDOS routines. Many games use these low
  30. level routines to quickly load graphics and sound effects.
  31.  
  32. Normal programs should, as said before, not use the lowlevel
  33. routines described here. However, it can still be interesting
  34. to read about it anyway, since it is always good to know what
  35. is actually happening inside the Amiga. 
  36.  
  37.  
  38.  
  39. 6.2  AMIGA DISK DRIVERS
  40.  
  41. The trackdisk device was designed to handle normal double sided
  42. double density (2DD) 3 1/2" disks (also called "1 megabyte
  43. disks"). The disk can be logically (fysically too, but that is
  44. not recommended) be divided into several small data areas where
  45. the actual data is stored.
  46.  
  47. Each data area, normally called "Sector", can store 512 bytes
  48. of data and 16 bytes of so called "label" data. The label area
  49. is used to identify the sector and what is stored here, and can
  50. therefore not be used to store raw data.
  51.  
  52. A group of eleven sectors is called "Cylinder" or "Track", and
  53. there exist 80 cylinders on each side of the disk. In total you
  54. can store 512 (bytes/sector) * 11 (sectors/cylinder) * 80
  55. (cylinders/side) * 2 (double sided disks) = 901120 bytes = 880KB
  56. (901120 / 1024). 
  57.  
  58. The trackdisk device will only handle whole cylinders. Even if
  59. you only want to read some sectors of a cylinder the complete
  60. cylinder will be loaded into the trackdisk's own memory buffer.
  61. This technique of reading and writing complete cylinders
  62. greatly improves the storage capacity and speed of the drives.
  63. The actual reading and writing process is very quick compared
  64. to the time it takes for the drive to move the head to the right
  65. position and start rotating the disk.
  66.  
  67. Your program will not notice that the trackdisk device is only
  68. using complete cylinders. If you want to read some sectors, the
  69. trackdisk device will read a complete cylinder, but gives you
  70. only those sectors you wanted. If you later want to read some
  71. sectors more it may happen that the device immediately can give
  72. you the data you wanted without having to access the disk.
  73.  
  74.  
  75.  
  76. 6.3  TRACKDISK DEVICE
  77.  
  78. The trackdisk device is controlled in the same manner as all
  79. other devices. You send your commands to it with help of a
  80. request block, and the device will send messages back to a
  81. specific reply port. So, to use the trackdisk device you have
  82. to: (Same as with most other devices.)
  83.  
  84.   1. Create a message port with which the device can send
  85.      messages back to us. See chapter 1 "Devices" for more
  86.      information.
  87.  
  88.   2. Allocate and preinitialize a request block.
  89.  
  90.   3. Open the trackdisk device.
  91.  
  92.  
  93.  
  94. 6.3.1  REQUESTBLOCK
  95.  
  96. A normal IOStdReq structure ("standard request block") is in
  97. most cases possible to use, but if you want to use some special
  98. features described further down you have to use the extended
  99. request block "IOExtTD". This IOExtTD structure is declared in
  100. header file "devices/trackdisk.h" as:
  101.  
  102. struct IOExtTD
  103. {
  104.   struct IOStdReq iotd_Req;
  105.   ULONG iotd_Count;
  106.   ULONG iotd_SecLabel;
  107. };
  108.  
  109.  
  110. iotd_Req:      The top part of the request block consists of
  111.                a standard request block (IOStdReq structure).
  112.  
  113. iotd_Count:    Each disk drive you are working with is assigned
  114.                a counter value which is increased each time a
  115.                disk is removed. If you are using the "extended"
  116.                commands (described below) the trackdisk device
  117.                will check the driver's count value with this
  118.                value. If the counter is greater than this value
  119.                the request will be aborted.
  120.                
  121.                If you are going to working with a disk it is
  122.                best to first get the driver's current count
  123.                value and store it here. You will then be sure
  124.                that the user will not change disks without you
  125.                knowing about it.
  126.                
  127. iotd_SecLabel: As described above, each sector has a 16 bytes
  128.                long "label" are. This label area is not used by
  129.                the track disk device. However, if you want to
  130.                read and/or write to this label area you should
  131.                use the "extended" read and write commands
  132.                described below, and this field should contain
  133.                a pointer to some memory where the label data
  134.                can be stored/read from.
  135.                
  136.                NOTE! If you intend to read some sectors' label
  137.                areas you must make sure you have allocated a
  138.                buffer that is large enough. 16 bytes is needed
  139.                for every sector you intend to read. If you want
  140.                to write new sector labels the memory must of
  141.                course also be large enough, but also
  142.                initialized with the values you want to write.
  143.  
  144.  
  145. Since this is an extended request block you have to use the
  146. CreateExtIO() function rather than CreateStdIO().
  147.  
  148.   Synopsis: ext_req = CreateExtIO( msg_port, size );
  149.  
  150.   ext_req:  (struct IORequest *) Pointer to the new extended
  151.             request block, or NULL if the request block could
  152.             not be created.
  153.  
  154.   msg_port: (struct MsgPort *) Pointer to the message port
  155.             the device should use to communicate with you.
  156.  
  157.   size:     (long) The number of bytes that should be allocated
  158.             for the extended request block. Use the function
  159.             sizeof() to find the exact number of bytes needed.
  160.  
  161.  
  162. If you are not going to use the "extended" commands which are
  163. described below, but only the normal commands, you do not need
  164. to use this extended request block. A normal standard request
  165. block will be enough. However, if you later would change your
  166. program so it starts to use the extended commands you have to
  167. remember to also change the type of request block. Usually it
  168. is best to always use an extended request block, although it
  169. sometimes it not strictly necessary.
  170.  
  171.  
  172.  
  173. 6.3.2  OPEN THE TRACKDISK DEVICE
  174.  
  175. Once you have opened a (reply) message port and created the
  176. request block you can open the trackdisk device. This is done
  177. with help of the now for us famous OpenDevice() function.
  178.  
  179.   Synopsis: error = OpenDevice( name, unit, req, flags );
  180.  
  181.   error:    (long) If OpenDevice() managed to open the device
  182.             it returns 0, else an error number is returned.
  183.  
  184.   name:     (char *) Name of the device you want to open.
  185.             The name of the trackdisk device is (surprise)
  186.             "trackdisk.device". This name has been defined
  187.             is the header file as "TD_NAME".
  188.             
  189.             When you are opening devices you should always try
  190.             to use the defined names rather than the actual
  191.             names. If Commodore would some day change the name
  192.             of the device (very unlikely though) you only have
  193.             to recompile your program with the new header
  194.             files, and your program will work again.
  195.  
  196.   unit:     (long) Which disk drive you want to use. All Amigas
  197.             are sold with at leas one internal drive (df0:),
  198.             but many have bought at lest one more drive. In
  199.             total there may exist up to four disk drivers.
  200.             Drive df0: has been given the unit number 0, df1:
  201.             the number 1, and so on...
  202.             
  203.             If you are trying to access a drive which does
  204.             not exist, OpenDevice() will fail. See Example 2.
  205.             
  206.   req:      (struct IORequest *) Pointer to the request block
  207.             you have created and initialized.
  208.  
  209.   flags:    (long) This field is ignored by the trackdisk
  210.             device.
  211.  
  212.  
  213.  
  214. 6.3.3  CLEAN UP
  215.  
  216. As always, do NOT forget to clean up after yourself! All opened
  217. message ports, request blocks, devices etc. must be closed and
  218. removed before your program may terminate. Here is what you
  219. have to do:
  220.  
  221.   1. Make sure that all your requests have been completed or
  222.      aborted.
  223.  
  224.   2. Close the trackdisk device with help of the CloseDevice()
  225.      function.
  226.  
  227.      Synopsis: CloseDevice( req );
  228.  
  229.      reg:      (struct IORequest *) Pointer to the device's
  230.                request block.
  231.  
  232.   3. Delete all request blocks you have created. Note that if
  233.      you have allocated extended request blocks you must use
  234.      the DeleteExtIO() function, but if you have allocated
  235.      standard request blocks you can use the DeleteStdIO()
  236.      function. As recommended above you should only use the
  237.      extended request blocks with the trackdisk device.
  238.  
  239.      Synopsis: DeleteExtIO( std_req, size );
  240.  
  241.      std_req:  (struct IOStdReq *) Pointer to the extended
  242.                request block you want to delete.
  243.  
  244.      size:     (long) The size of the request block, in bytes.
  245.  
  246.   4. Close all message ports you have opened. Do this by
  247.      calling the DeletePort() function. Note that all messages
  248.      still left at the port must be removed before you may
  249.      close the message port.
  250.  
  251.      Synopsis: DeletePort( msg_port );
  252.  
  253.      msg_port: (struct MsgPort *) Pointer to the MsgPort
  254.                structure that should be deallocated.
  255.  
  256.  
  257.  
  258. 6.4  COMMANDS
  259.  
  260. When the trackdisk device has successfully been opened you may
  261. start to send requests to it. The trackdisk device can do a lot
  262. of useful stuff, so there exist several commands that could be
  263. used. These commands can be divided into two groups. The first
  264. group consists of the "normal" commands. These commands will
  265. not check if the disk has been removed or changed. Note also
  266. that these commands can not be used to read or write the label
  267. areas of the sectors.
  268.  
  269. The second group consists of the "extended" commands - those
  270. commands that needs the extended IOExtTD structure. These
  271. commands will check the unit counter too see if the disk has
  272. been changed, and if so, the commands will automatically be
  273. aborted. These commands can be used if you want to access
  274. the sectors' label areas.
  275.  
  276. When you want to read and write data you have to give the
  277. "io_Data" field of the request block a pointer to some memory
  278. where all data you read will be placed, or if you are writing,
  279. where the data that should be written is stored. This buffer
  280. should be "word aligned" which means that it must start on
  281. an even byte address. The memory must also be of the type
  282. "Chip Memory" since the blitter will be used to speed up the
  283. operations. To fulfill both demands you should allocate the
  284. memory with help of the AllocMem function. See examples further
  285. down for more information.
  286.  
  287. The "io_Offset" value contains the offset value from which
  288. the trackdisk device will start to read/write from. The
  289. correct offset value is calculated with this formula:
  290.  
  291.   TD_SECTOR*( NUMSECS * 2 * cylinder + NUMSECS * head + sector )
  292.  
  293. The words in capital letters are defined in the header file
  294. "devices/trackdisk.h" as:
  295.   TD_SECTOR   512 (512 bytes / sector)
  296.   NUMSECS      11 (11 sectors / cylinder)
  297.  
  298. For example, if you want to start to read at side 0, cylinder 5,
  299. and sector 3, you should set the offset value to:
  300.  
  301.   TD_SECTOR * ( NUMSECS * 2 * 5 + NUMSECS * 0 + 3 );
  302.  
  303.  
  304. You tell the trackdisk device to read/write a specific number
  305. of bytes by setting the "io_Length" field to the number of
  306. bytes that should be transferred. Note that you must read
  307. complete sectors, and the length should therefore be set to:
  308. TD_SECTOR * "nr of desired sectors". (The trackdisk device
  309. will only read complete cylinders, but has nothing to do with
  310. this restriction of only reading complete sectors.)
  311.  
  312. The "io_Actual" filed will contain the number of actual bytes
  313. written/read. If this value is not the same as the "io_Length"
  314. something has happened. Check the "io_Error" field to find
  315. any error values. See below for more inforamtion about error
  316. messages.
  317.  
  318.  
  319.  
  320. 6.4.1  READ
  321.  
  322. Probably one of the most commonly used commands is undoubtedly
  323. the read command. If you simply want to read some data, and
  324. you do not care if the user has changed disks, you should use
  325. the "CMD_READ" command. However, most times it is best to check
  326. if the disk has been changed, before you start to read, and
  327. then you should use the extended "ETD_READ" command.
  328.  
  329. Here is an example: ("exreq" is a pointer to the request block,
  330. "buffer" is a pointer to some memory which is word aligned and
  331. is of the type chip memory. The buffer must at least be 2 * 512
  332. bytes.)
  333.  
  334.   /* We want to read: */
  335.   exreq->iotd_Req.io_Command = ETD_READ;
  336.  
  337.   /* Pointer to our buffer: */
  338.   exreq->iotd_Req.io_Data = (APTR) buffer;
  339.  
  340.   /* Read two sectors: */
  341.   exreq->iotd_Req.io_Length = TD_SECTORS * 2;
  342.  
  343.   /* Start to read at side 0, cylinder 5, and sector 3: */
  344.   exreq->iotd_Req.io_Offset = (LONG)
  345.    TD_SECTOR*( NUMSECS * 2 * 5 + NUMSECS * 0 + 3 );
  346.  
  347.   /* Do our request: */
  348.   DoIO( exreq );
  349.  
  350.  
  351.  
  352. 6.4.2  WRITE
  353.  
  354. Same as with reading, there exist two commands to write data.
  355. The shorter "CMD_WRITE" will simply write to the disk which is
  356. currently in the drive. The extended "ETD_WRITE" will check
  357. that the disk has not been changed.
  358.  
  359. Here is a similar example as the one above. This time we will
  360. try to write two sectors of data:
  361.  
  362.  
  363.   /* We want to write: */
  364.   exreq->iotd_Req.io_Command = ETD_WRITE;
  365.  
  366.   /* Pointer to our buffer: */
  367.   exreq->iotd_Req.io_Data = (APTR) buffer;
  368.  
  369.   /* Write two sectors: */
  370.   exreq->iotd_Req.io_Length = TD_SECTORS * 2;
  371.  
  372.   /* Start to write at side 0, cylinder 5, and sector 3: */
  373.   exreq->iotd_Req.io_Offset = (LONG)
  374.    TD_SECTOR*( NUMSECS * 2 * 5 + NUMSECS * 0 + 3 );
  375.  
  376.   /* Do our request: */
  377.   DoIO( exreq );
  378.  
  379.  
  380.  
  381. 6.4.3  MOTOR ON/OFF
  382.  
  383. You can tell the trackdisk device to start or stop the motor of
  384. the disk drive. Although you do not need to start the motor
  385. (this will be done automatically if you start to read or write),
  386. you must make sure to stop the drive after you have used it.
  387. You can either use the command "TD_MOTOR" or "ETD_MOTOR". The
  388. later will check that the disk has not been changed.
  389.  
  390. If the "io_Length" field is set to 0 the drive will be turned
  391. off. If the field is set to 1 the drive will be turned on. Here
  392. is an example ("exreq" is a pointer to the request block):
  393.  
  394.   /* Turn motor on/off: */
  395.   exreq->iotd_Req.io_Command = ETD_MOTOR;
  396.  
  397.   /* Turn the motor on: (0 = off, 1 = on) */
  398.   exreq->iotd_Req.io_Length = 1;
  399.  
  400.   /* Do our request: */
  401.   DoIO( exreq );
  402.  
  403.  
  404. Remember to always turn off the motor after you have used the
  405. drive! (If the motor already was on before you started to use
  406. it you do not need to turn it off. This means that some other
  407. device is also using the drive.)
  408.  
  409.  
  410.  
  411. 6.4.4  UPDATE THE DISK
  412.  
  413. When you write data to the disk it will not immediately be
  414. stored. The trackdisk device will as explained above only read
  415. and write complete cylinders, and if you do not write exactly
  416. an even number of cylinders, some data will be temporarily
  417. stored in the trackdisk device's internal memory buffer. When
  418. you later change cylinder the buffer will be copied out before
  419. the head is moved.
  420.  
  421. You can tell the trackdisk device to immediately copy the
  422. data in the buffer to the disk by sending a "CMD_UPDATE" or
  423. "ETD_UPDATE" command. The later command will as usual check if
  424. the disk has been removed or changed before the buffer is
  425. copied onto the disk. 
  426.  
  427. After you have written something to the disk and before you
  428. turn the motor off you should use this command. You will then
  429. be sure that all data you have written will actually be on the
  430. disk.
  431.  
  432. Here is an example:
  433.  
  434.   /* Update the disk (move any data still left in the buffer */
  435.   /* to the disk:                                            */
  436.   exreq->iotd_Req.io_Command = ETD_UPDATE;
  437.  
  438.   /* Do our request: */
  439.   DoIO( exreq );
  440.  
  441.  
  442.  
  443. 6.4.5  CLEAR BUFFER
  444.  
  445. You can tell the trackdisk device to clear it's internal
  446. buffer by sending a "CMD_CLEAR" or "ETD_CLEAR" command. Be
  447. sure that you do not clear anything that still has not been
  448. moved out onto the disk.
  449.  
  450. This clear command is recommended to use after you have noticed
  451. that the disks have been changed. This will ensure that old
  452. data from another disk will not be written to the new disk.
  453.  
  454. Here is an example:
  455.  
  456.   /* Clear the temporary buffer: */
  457.   exreq->iotd_Req.io_Command = ETD_CLEAR;
  458.  
  459.   /* Do our request: */
  460.   DoIO( exreq );
  461.  
  462.  
  463.  
  464. 6.4.6  POSITION THE HEAD
  465.  
  466. You can move the head to a specific position by sending a
  467. "TD_SEEK" or "ETD_SEEK" command. The head will simply be moved
  468. to the specified position in the "io_Offset" field, but no
  469. data will be read or written. This command is usually not
  470. needed since the head will always be placed on the correct
  471. position when you read or write data.
  472.  
  473. Here is an example:
  474.  
  475.   /* Position the head: */
  476.   exreq->iotd_Req.io_Command = ETD_SEEK;
  477.  
  478.   /* Move to position: side 1, cylinder 2, and sector 4: */
  479.   exreq->iotd_Req.io_Offset = (LONG)
  480.    TD_SECTOR*( NUMSECS * 2 * 2 + NUMSECS * 1 + 4 );
  481.  
  482.   /* Do our request: */
  483.   DoIO( exreq );
  484.  
  485.  
  486.  
  487. 6.4.7  FORMAT
  488.  
  489. With help of the "TD_FORMAT" or "ETD_FORMAT" command you can
  490. format a cylinder. You give the "io_Data" field a pointer to
  491. some data which will be written onto the new cylinder, and
  492. set the "io_Length" to NUMSECS * TD_SECTOR (one cylinder). The
  493. "io_Offset" field should be set to an offset value to the
  494. cylinder you want to format.
  495.  
  496. If you write data to a cylinder and you receive a hard write
  497. error (the cylinder is not formatted), you can try to reformat
  498. that cylinder. Note that it is usually best to tell the user
  499. to use some other disk rather than trying to correct this one.
  500. The user can then try to use "Diskdoctor" or similar programs
  501. to solve the disk problem.
  502.  
  503. Here is an example:
  504.  
  505.   /* We want to format one cylinder: */
  506.   exreq->iotd_Req.io_Command = ETD_FORMAT;
  507.  
  508.   /* Pointer to our buffer: (Must be at least one  */
  509.   /* cylinder of bytes large, NUMSECS * TD_SECTOR. */
  510.   exreq->iotd_Req.io_Data = (APTR) buffer;
  511.  
  512.   /* Format one cylinder: */
  513.   exreq->iotd_Req.io_Length = NUMSECS * TD_SECTOR;
  514.  
  515.   /* Format cylinder 5 on side 0: */
  516.   exreq->iotd_Req.io_Offset = (LONG)
  517.    TD_SECTOR*( NUMSECS * 2 * 5 + NUMSECS * 0 );
  518.  
  519.   /* Do our request: */
  520.   DoIO( exreq );
  521.  
  522.  
  523.  
  524. 6.4.8  REMOVE
  525.  
  526. You can send a "TD_REMOVE" command to the trackdisk device,
  527. and it will then increase the driver's count value. It will
  528. look like that the user has changed disks. 
  529.  
  530. Here is an example:
  531.  
  532.   /* Change disks: */
  533.   exreq->iotd_Req.io_Command = TD_REMOVE;
  534.  
  535.   /* Do our request: */
  536.   DoIO( exreq );
  537.  
  538.  
  539.  
  540. 6.4.9  GET THE DISK'S CURRENT COUNT NUMBER
  541.  
  542. The "extended" commands check if the disk has changed or not
  543. before they are executed. If the disk has changed the command
  544. is aborted. The commands compare the "iotd_Count" value of the
  545. request block with the disk's current count value. If the
  546. disk's count value is larger than the "iotd_Count" the command
  547. is aborted and the error flag "TDERR_DiskChanged" is set.
  548.  
  549. Before you use these extended commands you should therefore
  550. get the disk's current count value and store it in the request
  551. block. To get the disk's current count value you send an
  552. extended request block with the "TD_CHANGENUM" command set to
  553. the trackdisk device. The device will as soon as possible
  554. return your request with a copy of the current count value in
  555. the "io_Actual" field of the request block.
  556.  
  557. Here is an example:
  558.  
  559.   /* Store the current count value here: */
  560.   ULONG count_value;
  561.  
  562.   /* Get the disk's change count value: */
  563.   extreq->iotd_Req.io_Command = TD_CHANGENUM;
  564.  
  565.   /* Do our request, and return when completed: */
  566.   DoIO( extreq );
  567.   
  568.   /* Save the count value in the variable:  */
  569.   count_value = extreq->iotd_Req.io_Actual;
  570.  
  571.  
  572. After you have got the current count value you should give it
  573. the the request blocks which should later be used. The request
  574. block can then use the extended commands. Example:
  575.  
  576.   /* Give the request block the current count value: */
  577.   extreg->iotd_Count = count_value;
  578.  
  579.  
  580. After your program has received a "TDERR_DiskChanged" you should
  581. try to get the new count value before you attempt to access the
  582. new disk.
  583.  
  584.  
  585.  
  586. 6.4.10  CHECK IF THERE IS A DISK IN THE DRIVE OR NOT
  587.  
  588. With help of the trackdisk device can you check if there is a
  589. disk in a drive or not. To do this you use the "TD_CHANGESTATE"
  590. command. If there is a disk in the drive will the "io_Actual"
  591. field of the request will contain zero. On the other hand, if
  592. there is not a disk in the drive the field will contain a non 
  593. zero value.
  594.  
  595.   /* Check if there is a disk in the drive or not: */
  596.   extreq->iotd_Req.io_Command = TD_CHANGESTATE;
  597.  
  598.   /* Do our request, and return when completed: */
  599.   DoIO( extreq );
  600.  
  601.   /* Is there a disk in the drive? */
  602.   if( extreq->iotd_Req.io_Actual )
  603.     printf( "No disk in the drive!\n" );
  604.   else
  605.     printf( "There is a disk in the drive!\n" );
  606.  
  607.  
  608.  
  609. 6.4.11  CHECK IF THE DISK IS WRITE PROTECTED OR NOT
  610.  
  611. It can sometimes be very useful to know if the disk is write
  612. protected or not. With help of the "TD_PROTSTATUS" command we
  613. can easily check this. If the disk is write protected the
  614. "io_Actual" field will contain a non zero value. On the other
  615. hand, if the disk is not write protected the field will contain
  616. zero.
  617.  
  618.   /* Check if the disk is write protected or not: */
  619.   extreq->iotd_Req.io_Command = TD_PROTSTATUS;
  620.  
  621.   /* Do our request, and return when completed: */
  622.   DoIO( extreq );
  623.  
  624.   /* Is the disk write protected or not? */
  625.   if( extreq->iotd_Req.io_Actual )
  626.     printf( "The disk is write protected!\n" );
  627.   else
  628.     printf( "The disk is not write protected!\n" );
  629.  
  630.  
  631.  
  632. 6.4.12  GET DRIVE TYPE
  633.  
  634. The trackdisk device can also be used to tell you what type of
  635. disk drives are connected. If you send a request block with the
  636. "TD_GETDRIVETYPE" command set, the "io_Actual" field of the
  637. request block will either contain the flag "DRIVE3_5" or
  638. "DRIVE5_25" when it is returned. The "DRIVE3_5" means that it
  639. is a normal 3 1/2" disk drive, and the "DRIVE5_25" means that
  640. it is a 5 1/4 (IBM) disk drive.
  641.  
  642.   /* Check drive type: */
  643.   extreq->iotd_Req.io_Command = TD_GETDRIVETYPE;
  644.  
  645.   /* Do our request, and return when completed: */
  646.   DoIO( extreq );
  647.  
  648.   /* What type is it? */
  649.   if( extreq->iotd_Req.io_Actual == DISK3_5 )
  650.     printf( "It is a normal 3 1/2\" disk drive.\n" );
  651.   else
  652.     if( extreq->iotd_Req.io_Actual == DISK5_25 )
  653.       printf( "It is a 5 1/4\" disk drive.\n" );
  654.     else
  655.       printf( "It is a very strange disk drive!\n" );
  656.  
  657.  
  658.  
  659. 6.4.13  GET THE NUMBER OF TRACKS 
  660.  
  661. The "TD_GETNUMTRACKS" command is used to check how many tracks
  662. are used by the drive. When the request is returned you can
  663. check the "io_Actual" field of the request to get the number of
  664. tracks. A normal 3 1/2 disk drive uses 160 tracks (80 tracks /
  665. side).
  666.  
  667.   /* Get the number of tracks this drive is using: */
  668.   extreq->iotd_Req.io_Command = TD_GETNUMTRACKS;
  669.  
  670.   /* Do our request, and return when completed: */
  671.   DoIO( extreq );
  672.  
  673.   /* How many tracks? */
  674.   printf( "No tracks: %d\n", extreq->iotd_Req.io_Actual );
  675.  
  676.  
  677.  
  678. 6.5  ERRORS
  679.  
  680. When you are using the trackdisk device you will most definitely
  681. receive many errors. The "io_Error" field of the requestblock
  682. will contain 0 if the request was successfully executed, but if
  683. something failed it will contain one of the following error
  684. numbers: (Defined in the header file "devices/trackdisk.h".)
  685.  
  686.   Error code           Description
  687.   -------------------------------------------------------------
  688.   TDERR_NotSpecified   A strange error has occurred.
  689.   TDERR_NoSecHdr       Could not find a sector.
  690.   TDERR_BadSecPreamble Strange sector.
  691.   TDERR_BadSecID       Also a strange sector.
  692.   TDERR_BadHdrSum      Strange header.
  693.   TDERR_BadSecSum      Strange data areas.
  694.   TDERR_TooFewSecs     Missing some sectors.
  695.   TDERR_BadSecHdr      Yet another strange sector.
  696.   TDERR_WriteProt      The disk is write protected.
  697.   TDERR_DiskChanged    The disk has been removed/changed.
  698.   TDERR_SeekError      Could not reach track zero.
  699.   TDERR_NoMem          Not enough memory.
  700.   TDERR_BadUnitNum     Wrong unit number.
  701.   TDERR_BadDriveType   Strange drive type.
  702.   TDERR_DriveInUse     Someone is already using the drive.
  703.   TDERR_PostReset      Tea time, the system is resetted.
  704.  
  705.   There exist also four general device errors which all devices
  706.   may use: (Defined in header file "exec/errors.h".)
  707.  
  708.   IOERR_OPENFAIL       Could not open the device.
  709.   IOERR_ABORTED        Request aborted.
  710.   IOERR_NOCMD          Not a valid command.
  711.   IOERR_BADLENGTH      Bad length or value.
  712.   -------------------------------------------------------------
  713.  
  714.  
  715.  
  716. 6.6  EXAMPLES
  717.  
  718. Example 1
  719.   This program will use the Trackdisk Device to turn on and off
  720.   the internal disk drive's motor.
  721.  
  722. Example 2
  723.   This program demonstrates how you can check what went wrong
  724.   while you were using the Trackdisk Device. This example will
  725.   try to use drive DF3:, which most of us does not have, and
  726.   thus we will receive an error message. (Well if you have four
  727.   disk drives connected to your Amiga there will not be any
  728.   error message.)
  729.  
  730. Example 3
  731.   This example demonstrates how you can read data with help of
  732.   the Trackdisk Device. You give this program four arguments
  733.   (drive, head, cylinder and sector), and it will print out all
  734.   data in that sector. You only have to expand this program a
  735.   little and you will end up with a nice disk viewer.
  736.  
  737.   Example3 drive (0-3) head (0-1) cylinder (0-79) sector (0-10)
  738.  
  739. Example 4
  740.   This example contains a lot of small and useful functions
  741.   that does almost everything you ever would like to do with
  742.   the trackdisk device. The example has been written so you can
  743.   easily use the functions in your own programs.
  744.  
  745.  
  746.